home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
program
/
ddj0897.zip
/
DYN401.ZIP
/
threads
/
semaphor.d
< prev
next >
Wrap
Text File
|
1996-02-04
|
4KB
|
213 lines
/*
*
* Copyright (c) 1993-1996 Algorithms Corporation
* 3020 Liberty Hills Drive
* Franklin, TN 37067
*
* ALL RIGHTS RESERVED.
*
*
*
*/
#include <string.h>
defclass Semaphore {
object iObj; /* main object pointer */
char *iName; /* semaphore name */
int iCount;
int iMaximum;
object iWaiting_threads; /* LinkObject of waiting threads */
struct _Semaphore_iv_t *iNext; /* linked list of semaphores */
class:
struct _Semaphore_iv_t *cMsl; /* master semaphore list */
};
cmeth gNewSemaphore, <vNew> : New (object self, char *name, int cnt, int mx)
{
object obj = gNew(super);
ivType *iv = ivPtr(obj);
iObj = obj;
if (name) {
iName = Tnalloc(char, strlen(name)+1);
strcpy(iName, name);
}
iCount = cnt;
iMaximum = mx;
iNext = cMsl;
cMsl = iv;
return obj;
}
cmeth gNew()
{
return New(self, NULL, 1, 1);
}
imeth int gWaitFor(object self)
{
object ct;
INHIBIT_THREADER;
if (!(ct = gFindStr(Thread, NULL))) {
ENABLE_THREADER;
return 0;
}
if (iCount) {
iCount--;
ENABLE_THREADER;
return 0;
}
gWaitSemaphore(ct, self);
if (!iWaiting_threads)
iWaiting_threads = gNew(LinkObject);
gAddLast(iWaiting_threads, ct);
ENABLE_THREADER;
__dynace_yield();
return 0;
}
imeth gRelease : Release (object self, int cnt)
{
object thread;
iCount += cnt;
if (iCount > iMaximum)
iCount = iMaximum;
INHIBIT_THREADER;
while (iCount && iWaiting_threads && (thread = gFirst(iWaiting_threads))) {
gDisposeFirst(iWaiting_threads);
gReleaseSemaphore(thread);
iCount--;
}
ENABLE_THREADER;
return self;
}
imeth object gDispose, gDeepDispose (object self)
{
ivType *t, *p;
INHIBIT_THREADER;
while (iWaiting_threads && gFirst(iWaiting_threads))
Release(self, iMaximum);
if (iWaiting_threads)
gDispose(iWaiting_threads);
if (iName)
free(iName);
for (p=NULL, t=cMsl ; t ; p=t, t=t->iNext)
if (t == iv) {
if (p)
p->iNext = t->iNext;
else
cMsl = t->iNext;
break;
}
gDispose(super);
ENABLE_THREADER;
return NULL;
}
imeth object gGCDispose(object self)
{
ivType *t, *p;
INHIBIT_THREADER;
if (iWaiting_threads && gFirst(iWaiting_threads)) {
ENABLE_THREADER;
return NULL;
}
if (iName)
free(iName);
for (p=NULL, t=cMsl ; t ; p=t, t=t->iNext)
if (t == iv) {
if (p)
p->iNext = t->iNext;
else
cMsl = t->iNext;
break;
}
gDispose(super);
ENABLE_THREADER;
return NULL;
}
cmeth gFindStr, <vFind> (object self, char *name)
{
ivType *iv;
USE(self);
if (!name)
return NULL;
for (iv=cMsl ; iv ; iv=iNext)
if (iName && !strcmp(iName, name))
return iObj;
return NULL;
}
imeth int gCount(object self)
{
return iCount;
}
imeth char *gName(object self)
{
return iName;
}
/* the following method is used by the threader */
imeth gRemoveWaits(object self, object thrd)
{
object linkSequence, linkValue, thread;
if (!iWaiting_threads)
return self;
INHIBIT_THREADER;
linkSequence = gSequenceLinks(iWaiting_threads);
while (linkValue = gNext(linkSequence)) {
thread = gValue(linkValue);
if (thread == thrd) {
gDispose(linkValue);
break;
}
}
if (linkValue)
gDispose(linkSequence);
ENABLE_THREADER;
return self;
}
imeth gCopy, gDeepCopy (object self)
{
return gShouldNotImplement(self, "Copy/DeepCopy");
}
/*
*
* Copyright (c) 1993-1996 Algorithms Corporation
* 3020 Liberty Hills Drive
* Franklin, TN 37067
*
* ALL RIGHTS RESERVED.
*
*
*
*/